﻿using System;

namespace HCore
{
    public abstract class HGame
    {
        public PrecisionTimer timer => _timer;

        public RandomGen randomGen => _randomGen;

        public EntityManager entityMgr => _entityMgr;

        public MessageDispatcher dispatcher => _dispatcher;

        public ClientNetworkManager networkMgr => _networkMgr;

        public CommandManager commandMgr => _commandMgr;

        public string playerName => _playerName;

        public int playerId => _playerId;

        public bool inBattle => _inBattle;

        private readonly EntityManager _entityMgr;
        private readonly MessageDispatcher _dispatcher;
        private readonly PrecisionTimer _timer;
        private readonly RandomGen _randomGen;
        private readonly CommandManager _commandMgr;
        private readonly ClientNetworkManager _networkMgr;
        private readonly string _playerName;
        protected int _playerId;
        protected bool _inBattle;

        public HGame(LaunchParams launchParams)
        {
            _networkMgr = ClientNetworkManager.Get(launchParams.connectIp, launchParams.connectPort);

            if (launchParams.recordData != null)
                _commandMgr = new RecordCommandManager(this, launchParams.recordData);
            else
                _commandMgr = new InputCommandManager(this);

            _timer = new PrecisionTimer(launchParams.frameRate);
            _randomGen = new RandomGen(launchParams.randomSeed);
            _entityMgr = new EntityManager();
            _dispatcher = new MessageDispatcher(_entityMgr, _timer);
            _playerName = launchParams.playerName;
            _inBattle = false;
        }

        public abstract void Update();

        public virtual void Dispose()
        {
            _commandMgr.Dispose();
            _entityMgr.Dispose();
        }

        public bool SaveRecord(string path)
        {
            // 保存录像
            RecordData recordData = new RecordData(commandMgr.turnMap, commandMgr.serverProxies);
            OutputMemeryBitStream output = new OutputMemeryBitStream();
            recordData.Write(output);
            FileUtility.Save(output, path);
            Log("RecordData Saved");
            return true;
        }

        public void Log(string str)
        {
            Logger.Log("[TotalTime: " + _timer.totalTime +"][" + DateTime.Now.ToString("hh:mm:ss fff") + "][Client " + _timer.frameCount + " ] " + str);
        }
    }
}